package org.aceor.mddal.gateway.util;

import com.google.common.base.Strings;
import org.aceor.mddal.common.sqlparser.result.object.OrderByColumn;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

/**
 * Created by lxue on 16/4/16.
 */
public class ResultSetUtil {
    private static final Logger log = LoggerFactory.getLogger(ResultSetUtil.class);

    public static Object getValue(final String columnName, final String columnAlias, final ResultSet resultSet) throws SQLException {
        if (Strings.isNullOrEmpty(columnAlias)
                && Strings.isNullOrEmpty(columnName)) {
            throw new IllegalArgumentException("orderby column's name and alias are empty!");
        }
        Object result;
        //优先以别名取值
        if (!Strings.isNullOrEmpty(columnAlias)) {
            result = resultSet.getObject(columnAlias);
        } else {
            result = resultSet.getObject(columnName);
        }
        return result;
    }

    /**
     * 根据返回值类型返回特定类型的结果.
     *
     * @param value       原始结果
     * @param convertType 返回值类型
     * @return 特定类型的返回结果
     */
    public static Object convertValue(final Object value, final Class<?> convertType) {
        if (null == value) {
            return convertNullValue(convertType);
        } else if (value instanceof Date) {
            return (Date) value;
        } else if (value instanceof Timestamp) {
            return (Timestamp) value;
        } else if (value instanceof Number) {
            return convertNumberValue(value, convertType);
        } else {
            if (String.class.equals(convertType)) {
                return value.toString();
            } else {
                return value;
            }
        }
    }

    private static Object convertNumberValue(final Object value, final Class<?> convertType) {
        Number number = (Number) value;
        switch (convertType.getName()) {
            case "short":
                return number.shortValue();
            case "int":
                return number.intValue();
            case "long":
                return number.longValue();
            case "double":
                return number.doubleValue();
            case "float":
                return number.floatValue();
            case "java.math.BigDecimal":
                if (number instanceof BigDecimal) {
                    return number;
                } else {
                    return new BigDecimal(number.toString());
                }
            case "java.lang.String"://这里的确走的到,可以Number类型也能是String类型?
            case "java.lang.Object":
                return number.toString();
            default:
                throw new RuntimeException("Unsupported data type :" + convertType);
        }
    }

    private static Object convertNullValue(final Class<?> convertType) {
        switch (convertType.getName()) {
            case "short":
                return (short) 0;
            case "int":
                return 0;
            case "long":
                return 0L;
            case "double":
                return 0D;
            case "float":
                return 0F;
            case "java.math.BigDecimal":
            case "java.lang.Object":
            case "java.lang.String":
            case "java.sql.Date":
            case "java.sql.Timestamp":
                return null;
            default:
                throw new RuntimeException("Unsupported data type :" + convertType);
        }
    }

    public static int compareTo(Object thisValue, Object otherValue, OrderByColumn.OrderByType orderByType) {
        int result = DataTypeUtil.getTypeOfObject(thisValue).compare(thisValue, otherValue);
        return orderByType == OrderByColumn.OrderByType.ASC ? result : -result;
    }
}
